package com.ericsson.enap.modules.ossalarm.thread;

import com.ericsson.common.mapper.JsonMapper;
import com.ericsson.common.util.DateUtils;
import com.ericsson.common.util.FileUtil;
import com.ericsson.common.util.Jdk8DateUtils;
import com.ericsson.enap.modules.ossalarm.entity.*;
import com.ericsson.enap.modules.ossalarm.mapper.OssAlarmMapper;
import com.ericsson.enap.modules.ossalarm.mapper.EnipVisExcelModuleDetailMapper;
import com.ericsson.enap.modules.ossalarm.mapper.EnipVisExcelModuleMapper;
import com.ericsson.enap.modules.sys.entity.EnipNetelement;
import org.slf4j.Logger;
import org.springframework.kafka.core.KafkaTemplate;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

/**
 * 处理ENM告警信息的线程
 * @author yh
 */
public class OssDealAlarmThread extends Thread{
    private Queue msgQueue;
    private Logger log;
    private Map<String, EnipNetelement> netElementMap;
    private OssAlarmMapper ossAlarmMapper;
    private EnipVisExcelModuleMapper enipVisExcelModuleMapper;
    private EnipVisExcelModuleDetailMapper visExcelModuleDetailMapper;
    private String tpXmlPathTxtCnAlarm;
    private KafkaTemplate<String, String> kafkaTemplate;
    public OssDealAlarmThread(KafkaTemplate<String, String> kafkaTemplate, String tpXmlPathTxtCnAlarm, EnipVisExcelModuleMapper enipVisExcelModuleMapper, EnipVisExcelModuleDetailMapper visExcelModuleDetailMapper, OssAlarmMapper ossAlarmMapper, Map<String, EnipNetelement> netElementMap, Queue e, Logger log){
        this.kafkaTemplate=kafkaTemplate;
        this.tpXmlPathTxtCnAlarm=tpXmlPathTxtCnAlarm;
        this.enipVisExcelModuleMapper = enipVisExcelModuleMapper;
        this.visExcelModuleDetailMapper=visExcelModuleDetailMapper;
        this.ossAlarmMapper=ossAlarmMapper;
        this.netElementMap=netElementMap;
        this.msgQueue=e;
        this.log=log;
    }
    @Override
    public void run() {
        while(true){
            if(!this.msgQueue.isEmpty()) {
                String msg = null;
                try {
                     msg= this.msgQueue.poll().toString();
                     String []msgArr=msg.split("\n");
                     CnAlarmEntity cnAlarmEntity=new CnAlarmEntity();
                     for(String tmp:msgArr){
                         if(tmp.contains("-EventTime")){
                             String eventtime= DateUtils.formattedDateTime(tmp.substring(tmp.indexOf("=")+1,tmp.length()),"yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss");
                             cnAlarmEntity.setEventTime(eventtime);
                         }else if(tmp.contains("PerceivedSeverity")){
                             cnAlarmEntity.setAlarmLevel(Long.parseLong(tmp.substring(tmp.indexOf("=")+1,tmp.length())));
                         }else if(tmp.contains("SpecificProblemText")){
                             cnAlarmEntity.setEnglishTitleid(tmp.substring(tmp.indexOf("=")+1,tmp.length()));
                         }else if(tmp.contains("-AlarmId")){
                             cnAlarmEntity.setAlarmId(tmp.substring(tmp.indexOf("=")+1,tmp.length()));
                         }else if(tmp.contains("-Fdn=NetworkElement=")){
                             String netName=tmp.substring(20,tmp.length());
                             EnipNetelement netelement=this.netElementMap.get(netName);
                             cnAlarmEntity.setNetName(netName);
                             cnAlarmEntity.setNetId(netelement.getId());
                             cnAlarmEntity.setNetType(netelement.getType());
                         }
                     }
                    analysisCnAlarm(cnAlarmEntity);
                }catch(Exception ex){
                    log.error("OssDealAlarmThread"+ex.getMessage()+":msg:"+msg);
                }
            }else{
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }

    /**
     * 分析告警消息，并执行相应的操作
     * @param cnAlarmEntity
     */
    private void analysisCnAlarm(CnAlarmEntity cnAlarmEntity){
        if(cnAlarmEntity.getAlarmLevel().equals(0l)){
            //PerceivedSeverity=0 Indeterminate 不做任何处理
        }else if(cnAlarmEntity.getAlarmLevel().equals(5l)){
            //5级，根据netid和alarmid读取库中的数据状态，
            // 如果为5，不做任何操作；
            // 否则：发送KAFKA清除告警消息（如果库中配置(enip_chinese_mq_dict:nettype、englishtitle)），并将库中的告警状态置为0（告警消除）
            List<CnAlarmEntity> cnAlarmEntities=this.ossAlarmMapper.queryCnAlarmMsg(cnAlarmEntity.getNetId(),cnAlarmEntity.getAlarmId());
            if(cnAlarmEntities.size()>0){
                CnAlarmEntity cnAlarmEntityTmp=cnAlarmEntities.get(0);
                if(!cnAlarmEntityTmp.getAlarmLevel().equals(5l)){
                    cnAlarmEntity.setStatus(0l);
                    List<CnAlarmDictEntity> cnAlarmDictEntities=this.ossAlarmMapper.queryCnAlarmConfig(cnAlarmEntity.getNetType(),cnAlarmEntity.getEnglishTitleid());
                    if(cnAlarmDictEntities.size()>0){
                        //获取插入时的alarmSeq 用于清除告警
                        cnAlarmEntity.setAlarmSeq(cnAlarmEntityTmp.getAlarmSeq());
                        //发送kafka
                        String cancelMsg=createMqMessage(cnAlarmDictEntities.get(0),cnAlarmEntity);
                        sendAlarm(cancelMsg);
                        cnAlarmEntity.setCancelAlarmMsg(cancelMsg);
                    }
                    cnAlarmEntity.setUpdateTime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));
                    this.ossAlarmMapper.updateCnAlarmMsgStatus(cnAlarmEntity);
                }
            }
        }else{
            //除0和5外的其它等级告警，根据netid和alarmid读取库中的数据，
            // 如果存在数据，不做任何操作；
            // 否则：发送KAFKA告警消息（如果库中配置(enip_chinese_mq_dict:nettype、englishtitle)），执行EOPS模板（如果库中配置(enip_chinese_mq_dict:nettype、englishtitle)），插入数据到告警表（enip_chinese_alarm_mq）
            List<CnAlarmEntity> cnAlarmEntities=this.ossAlarmMapper.queryCnAlarmMsg(cnAlarmEntity.getNetId(),cnAlarmEntity.getAlarmId());
            if(cnAlarmEntities.size()==0){
                List<CnAlarmDictEntity> cnAlarmDictEntities=this.ossAlarmMapper.queryCnAlarmConfig(cnAlarmEntity.getNetType(),cnAlarmEntity.getEnglishTitleid());
                cnAlarmEntity.setStatus(1l);
                if(cnAlarmDictEntities.size()>0){
                    cnAlarmEntity.setAlarmSeq(Jdk8DateUtils.now().formatDateTime("yyyyMMddHHmmssSSS"));
                    //发送kafka
                    String createMsg=createMqMessage(cnAlarmDictEntities.get(0),cnAlarmEntity);
                    sendAlarm(createMsg);
                    cnAlarmEntity.setCreateAlarmMsg(createMsg);
                }
                if(cnAlarmDictEntities.size()>0&&null!=cnAlarmDictEntities.get(0).getVisExcelId()) {
                    //执行eops
                    EnipNetelement netelement=this.netElementMap.get(cnAlarmEntity.getNetName());
                    String eopsResult=null;
//                    try {
                        eopsResult="EOPS";//executeEops(cnAlarmDictEntities.get(0).getVisExcelId(),netelement);
//                    } catch (IOException e) {
//                        log.error("run eops error:"+e.getMessage());
//                    }
                    cnAlarmEntity.setEopsLog(eopsResult);
                }
                cnAlarmEntity.setCreateTime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));
                this.ossAlarmMapper.insertEnipChineseAlarmMq(cnAlarmEntity);
            }
        }
    }

    private String executeEops(Long excelId,EnipNetelement netelement) throws IOException {
        //根据模板ID读取模板信息并写入到文件中
        List<Object> jsonList = new ArrayList<Object>();
        EnipVisExcelModule queryModule = new EnipVisExcelModule();
        queryModule.setExcelId(excelId.intValue());
        List<EnipVisExcelModule> enipVisExcelModules = this.enipVisExcelModuleMapper.selectVisExcelModuleList(queryModule);
        EnipVisExcelModuleDetail queryModuleDetail = new EnipVisExcelModuleDetail();
        List<EnipVisExcelModuleDetail> enipVisExcelModuleDetailList=new ArrayList<>();
        for(EnipVisExcelModule excelModule : enipVisExcelModules) {
            queryModuleDetail.setExcelId(excelModule.getExcelId());
            queryModuleDetail.setModuleId(excelModule.getId());
            enipVisExcelModuleDetailList.addAll(this.visExcelModuleDetailMapper.selectVisExcelModuleDetailList(queryModuleDetail));
        }
        for (EnipVisExcelModuleDetail detailItem : enipVisExcelModuleDetailList) {
            //SYSTEM-INPUT:输入参数命令；SYSTEM-STOP:模块结束提示标识
            if (!detailItem.getConfCmd().equals("SYSTEM-INPUT") && !detailItem.getConfCmd().contains("SYSTEM-STOP")) {
                jsonList.add(detailItem);
            }
        }
        // 将模板的数据写入到json文件中
        String jsonPath =this.tpXmlPathTxtCnAlarm;
        File fileTxt=writeDataToFile(jsonList,jsonPath,enipVisExcelModules.get(0).getExcelId(),enipVisExcelModules.get(0).getId());
        return executeCmd(jsonPath,fileTxt,netelement);
    }

    /**
     * 数据写入文件
     * @param jsonList
     * @param jsonPath
     * @param excelId
     * @param moduleId
     * @return
     * @throws IOException
     */
    private File writeDataToFile(List<Object> jsonList,String jsonPath,Integer excelId,Integer moduleId) throws IOException {
        File workPath = new File(jsonPath);
        if(!workPath.exists()){
            workPath.mkdirs();
        }
        File fileTxt = new File(jsonPath + File.separator + excelId + "_" + moduleId + ".txt");
        if (fileTxt.exists()) {
            fileTxt.delete();
        }
        fileTxt.createNewFile();
        FileUtil.writeToFile(jsonList, fileTxt);
        return fileTxt;
    }

    /**
     * 执行模板
     * @param jsonPath
     * @param fileTxt
     * @param net
     * @return
     */
    private String executeCmd(String jsonPath,File fileTxt,EnipNetelement net){
        Process proc = null;
        BufferedReader br;
        BufferedReader brError;
        String line;
        String lineError;
        StringBuilder sb=new StringBuilder();
        try {
            String[] cmd = new String[3];
            cmd[0] = "sh";
            cmd[1] = "-c";
            cmd[2] = "/usr/bin/perl -w /opt/Ericsson/core/bin/eops.pl";
            cmd[2] += " -ip " + net.getIp4();
            cmd[2] += " -user " + net.getUsername() + " -password '" + net.getPassword();
            cmd[2] += "' -conf_file " + jsonPath + File.separator + fileTxt.getName();
            cmd[2] += " -rootpassword '" + net.getPassword()+"'";
            try {
                System.out.println("path: "+jsonPath);
                System.out.println("cmd: "+cmd[2]);
                proc = Runtime.getRuntime().exec(cmd);
            } catch (IOException e) {
                e.printStackTrace();
            }
            br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            brError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            try {
                while ((line = br.readLine()) != null) {
                        sb.append(line+"\n");
                }
                while ((lineError = brError.readLine()) != null) {
                    sb.append(lineError+"\n");
                }
                proc.waitFor();
                System.out.println("proc end");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            proc.destroy();
        }
        return sb.toString();
    }

    public String createMqMessage(CnAlarmDictEntity cnAlarmDictEntity,CnAlarmEntity cnAlarmEntity) {
        String alarmSeq = Jdk8DateUtils.now().formatDateTime("yyyyMMddHHmmssSSS");
        OssAlarmMessage message = new OssAlarmMessage();
        message.setSystemId(cnAlarmDictEntity.getSystemid()); //三方系统ID
        message.setMessageType(cnAlarmDictEntity.getMessagetype()); //消息分类-一级分类
        message.setSubMessageType("11000"); //消息分类-二级分类
        message.setAlarmTitle(cnAlarmDictEntity.getAlarmtitle()); //告警标题
        message.setAlarmStatus(cnAlarmEntity.getStatus().toString()); //告警状态 1：活动告警；0：清除告警
        message.setAlarmId(cnAlarmEntity.getNetId()+cnAlarmEntity.getAlarmId()+cnAlarmEntity.getAlarmSeq()); //告警ID  产生告警与消除告警ID相同
        message.setAlarmSeq(alarmSeq);//告警上报的消息序号 ,每产生一条告警包括消除告警，会产生唯一序号
        message.setAlarmType(cnAlarmDictEntity.getAlarmtype()); //告警类型
        message.setOrigSeverity(cnAlarmDictEntity.getOrigseverity()); //原始级别
        message.setEventTime(cnAlarmEntity.getEventTime());  //告警发生时间
        message.setSpecificProblemID(cnAlarmDictEntity.getSpecificproblemid()); //告警问题原因ID。厂家告警ID
        message.setSpecificProblem(cnAlarmDictEntity.getSpecificproblem()); //告警问题原因
        message.setObjectType(cnAlarmDictEntity.getObjecttype()); //设备类型
        message.setObjectUID(cnAlarmEntity.getNetId().toString()); //告警定位对象UID
        message.setObjectName(cnAlarmEntity.getNetName());  //网元名
        message.setSubObjectUID(cnAlarmEntity.getNetId().toString()); //告警定位子对象UID
        message.setSubObjectType(cnAlarmDictEntity.getObjecttype());  //告警对象类型
        message.setSubObjectName(cnAlarmEntity.getNetName()); //告警定位子对象啊名称

        message.setVendorName(cnAlarmDictEntity.getVendorname()); //厂家
        message.setProvince(cnAlarmDictEntity.getProvince()); //省份
        message.setCity(cnAlarmDictEntity.getCity()); //地市
        message.setAddInfo(cnAlarmEntity.getAlarmId());//告警定位信息 为空可以显示告警正文
        return JsonMapper.toJsonString(message);
    }

    private void sendAlarm(String alarmMessage) {
        log.info("send kafka start===================================="+alarmMessage);
        kafkaTemplate.send("ericsson_expert_system", alarmMessage);
        log.info("send kafka end======================================");
    }
}
